package com.ruoyi.system.service.impl;



import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.ruoyi.common.constant.SmsConstant;
import com.ruoyi.common.enums.ProcessEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSONObject;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class SmsService {

    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.signName}")
    private String signName;

    @Value("${aliyun.templateCode}")
    private String templateCode;

    @Value("${aliyun.endpoint}")
    private String endpoint;



    @Autowired
    private RedisTemplate redisTemplate;

    private Client client;

    @PostConstruct
    public void init() throws Exception {
        Config config = new Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret)
                .setEndpoint(endpoint);
        client = new Client(config);
    }

    public String sendSms(String mobile) throws Exception {
        // 检验手机号码
        boolean isPhone = isPhone(mobile);
        if (!isPhone) {
            return ProcessEnum.PHONE_FORMAT_ERROR;
        }
        // 校验是否重复发送
        Object code = redisTemplate.opsForValue().get(SmsConstant.REDIS_SMS_MOBILE + mobile);
        if (code != null) {
            return ProcessEnum.SMS_FREQUENTLY;
        }
        String kaptcha = this.getKaptcha();
        Map <String, String> map = new HashMap <>(1);
        map.put("code", kaptcha);
        String templateParam = JSONObject.toJSONString(map);

        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers(mobile)
                .setSignName(signName)
                .setTemplateCode(templateCode)
                .setTemplateParam(templateParam);

        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        if ( "OK".equals(sendSmsResponse.getBody().getCode()) ){

            redisTemplate.opsForValue().set(SmsConstant.REDIS_SMS_MOBILE + mobile, kaptcha);
            redisTemplate.expire(SmsConstant.REDIS_SMS_MOBILE + mobile, 30, TimeUnit.SECONDS);
            return ProcessEnum.SUCCESS;
        };

        return ProcessEnum.SMS_FAILED;
    }

    public Boolean checkKaptcha(String mobile, String kaptcha) {
        Object s = this.redisTemplate.opsForValue().get(SmsConstant.REDIS_SMS_MOBILE + mobile);
        return s != null && s.equals(kaptcha);
    }

    private String getKaptcha() {
        StringBuilder str = new StringBuilder();
        Random random = new Random();

        for (int i = 0; i < 6; i++) {
            int randomInt = random.nextInt(10);
            str.append(randomInt);
        }
        return str.toString();
    }

    public static boolean isPhone(String phone) {
        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
        if (phone.length() != 11) {
            return false;
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            return m.matches();
        }
    }
}
